{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# 向量\n",
    "> 有值和方向的量\n",
    "\n",
    "假设在二维平面有一个点 x = 2, y = 1\n",
    "\n",
    "\\begin{equation}\\vec{v} = \\begin{bmatrix}2 \\\\ 1 \\end{bmatrix}\\end{equation}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.core.interactiveshell import InteractiveShell\n",
    "InteractiveShell.ast_node_interactivity = \"last_expr\"\n",
    "# %matplotlib inline\n",
    "import math\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "v = np.array([2,1])\n",
    "\n",
    "origin = [0], [0]\n",
    "plt.axhline()\n",
    "plt.axvline()\n",
    "plt.axis('equal')\n",
    "plt.grid()\n",
    "plt.ticklabel_format(style='sci', axis='both', scilimits=(0,0))\n",
    "plt.quiver(*origin, *v, scale=10, color='r')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## 计算向量对应的标量\n",
    "\n",
    "\\begin{equation}\\|\\vec{v}\\| = \\sqrt{v_{1}\\;^{2} + v_{2}\\;^{2}}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}\\|\\vec{v}\\| = \\sqrt{2^{2} + 1^{2}}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}\\|\\vec{v}\\| = \\sqrt{4 + 1}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}\\|\\vec{v}\\| = \\sqrt{5} \\approx 2.24\\end{equation}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.23606797749979"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vMag = math.sqrt(v[0]**2 + v[1]**2)\n",
    "vMag"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "对于n维空间的情况\n",
    "\n",
    "\\begin{equation}\\|\\vec{v}\\| = \\sqrt{v_{1}\\;^{2} + v_{2}\\;^{2} ... + v_{n}\\;^{2}}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.23606797749979"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vMag = np.linalg.norm(v) # 使用 norm 方法\n",
    "vMag"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function norm in module numpy.linalg:\n",
      "\n",
      "norm(x, ord=None, axis=None, keepdims=False)\n",
      "    Matrix or vector norm.\n",
      "    \n",
      "    This function is able to return one of eight different matrix norms,\n",
      "    or one of an infinite number of vector norms (described below), depending\n",
      "    on the value of the ``ord`` parameter.\n",
      "    \n",
      "    Parameters\n",
      "    ----------\n",
      "    x : array_like\n",
      "        Input array.  If `axis` is None, `x` must be 1-D or 2-D.\n",
      "    ord : {non-zero int, inf, -inf, 'fro', 'nuc'}, optional\n",
      "        Order of the norm (see table under ``Notes``). inf means numpy's\n",
      "        `inf` object.\n",
      "    axis : {int, 2-tuple of ints, None}, optional\n",
      "        If `axis` is an integer, it specifies the axis of `x` along which to\n",
      "        compute the vector norms.  If `axis` is a 2-tuple, it specifies the\n",
      "        axes that hold 2-D matrices, and the matrix norms of these matrices\n",
      "        are computed.  If `axis` is None then either a vector norm (when `x`\n",
      "        is 1-D) or a matrix norm (when `x` is 2-D) is returned.\n",
      "    \n",
      "        .. versionadded:: 1.8.0\n",
      "    \n",
      "    keepdims : bool, optional\n",
      "        If this is set to True, the axes which are normed over are left in the\n",
      "        result as dimensions with size one.  With this option the result will\n",
      "        broadcast correctly against the original `x`.\n",
      "    \n",
      "        .. versionadded:: 1.10.0\n",
      "    \n",
      "    Returns\n",
      "    -------\n",
      "    n : float or ndarray\n",
      "        Norm of the matrix or vector(s).\n",
      "    \n",
      "    Notes\n",
      "    -----\n",
      "    For values of ``ord <= 0``, the result is, strictly speaking, not a\n",
      "    mathematical 'norm', but it may still be useful for various numerical\n",
      "    purposes.\n",
      "    \n",
      "    The following norms can be calculated:\n",
      "    \n",
      "    =====  ============================  ==========================\n",
      "    ord    norm for matrices             norm for vectors\n",
      "    =====  ============================  ==========================\n",
      "    None   Frobenius norm                2-norm\n",
      "    'fro'  Frobenius norm                --\n",
      "    'nuc'  nuclear norm                  --\n",
      "    inf    max(sum(abs(x), axis=1))      max(abs(x))\n",
      "    -inf   min(sum(abs(x), axis=1))      min(abs(x))\n",
      "    0      --                            sum(x != 0)\n",
      "    1      max(sum(abs(x), axis=0))      as below\n",
      "    -1     min(sum(abs(x), axis=0))      as below\n",
      "    2      2-norm (largest sing. value)  as below\n",
      "    -2     smallest singular value       as below\n",
      "    other  --                            sum(abs(x)**ord)**(1./ord)\n",
      "    =====  ============================  ==========================\n",
      "    \n",
      "    The Frobenius norm is given by [1]_:\n",
      "    \n",
      "        :math:`||A||_F = [\\sum_{i,j} abs(a_{i,j})^2]^{1/2}`\n",
      "    \n",
      "    The nuclear norm is the sum of the singular values.\n",
      "    \n",
      "    References\n",
      "    ----------\n",
      "    .. [1] G. H. Golub and C. F. Van Loan, *Matrix Computations*,\n",
      "           Baltimore, MD, Johns Hopkins University Press, 1985, pg. 15\n",
      "    \n",
      "    Examples\n",
      "    --------\n",
      "    >>> from numpy import linalg as LA\n",
      "    >>> a = np.arange(9) - 4\n",
      "    >>> a\n",
      "    array([-4, -3, -2, -1,  0,  1,  2,  3,  4])\n",
      "    >>> b = a.reshape((3, 3))\n",
      "    >>> b\n",
      "    array([[-4, -3, -2],\n",
      "           [-1,  0,  1],\n",
      "           [ 2,  3,  4]])\n",
      "    \n",
      "    >>> LA.norm(a)\n",
      "    7.745966692414834\n",
      "    >>> LA.norm(b)\n",
      "    7.745966692414834\n",
      "    >>> LA.norm(b, 'fro')\n",
      "    7.745966692414834\n",
      "    >>> LA.norm(a, np.inf)\n",
      "    4.0\n",
      "    >>> LA.norm(b, np.inf)\n",
      "    9.0\n",
      "    >>> LA.norm(a, -np.inf)\n",
      "    0.0\n",
      "    >>> LA.norm(b, -np.inf)\n",
      "    2.0\n",
      "    \n",
      "    >>> LA.norm(a, 1)\n",
      "    20.0\n",
      "    >>> LA.norm(b, 1)\n",
      "    7.0\n",
      "    >>> LA.norm(a, -1)\n",
      "    -4.6566128774142013e-010\n",
      "    >>> LA.norm(b, -1)\n",
      "    6.0\n",
      "    >>> LA.norm(a, 2)\n",
      "    7.745966692414834\n",
      "    >>> LA.norm(b, 2)\n",
      "    7.3484692283495345\n",
      "    \n",
      "    >>> LA.norm(a, -2)\n",
      "    nan\n",
      "    >>> LA.norm(b, -2)\n",
      "    1.8570331885190563e-016\n",
      "    >>> LA.norm(a, 3)\n",
      "    5.8480354764257312\n",
      "    >>> LA.norm(a, -3)\n",
      "    nan\n",
      "    \n",
      "    Using the `axis` argument to compute vector norms:\n",
      "    \n",
      "    >>> c = np.array([[ 1, 2, 3],\n",
      "    ...               [-1, 1, 4]])\n",
      "    >>> LA.norm(c, axis=0)\n",
      "    array([ 1.41421356,  2.23606798,  5.        ])\n",
      "    >>> LA.norm(c, axis=1)\n",
      "    array([ 3.74165739,  4.24264069])\n",
      "    >>> LA.norm(c, ord=1, axis=1)\n",
      "    array([ 6.,  6.])\n",
      "    \n",
      "    Using the `axis` argument to compute matrix norms:\n",
      "    \n",
      "    >>> m = np.arange(8).reshape(2,2,2)\n",
      "    >>> LA.norm(m, axis=(1,2))\n",
      "    array([  3.74165739,  11.22497216])\n",
      "    >>> LA.norm(m[0, :, :]), LA.norm(m[1, :, :])\n",
      "    (3.7416573867739413, 11.224972160321824)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(np.linalg.norm)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 计算向量的方向（角度）\n",
    "\\begin{equation}tan(\\theta) = \\frac{1}{2}\\end{equation}\n",
    "\n",
    "\\begin{equation}\\theta = tan^{-1} (0.5) \\approx 26.57^{o}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "26.56505117707799"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "angle = math.degrees(math.atan(v[1] / v[0])) # ard (arctan) → degree\n",
    "angle"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-63.43494882292201\n"
     ]
    }
   ],
   "source": [
    "print(math.degrees(math.atan(-2 / 1)))       # 角度应该在第二象限"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "> [atan2](https://docs.scipy.org/doc/numpy/reference/generated/numpy.arctan2.html?highlight=atan2)文档\n",
    "\n",
    "![atan2](http://bazhou.blob.core.windows.net/learning/mpp/atan2.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": true,
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "26.56505117707799\n",
      "153.434948822922\n"
     ]
    }
   ],
   "source": [
    "print(np.degrees(np.arctan2(v[1], v[0])))\n",
    "s = np.array([-2,1])\n",
    "print (np.degrees(np.arctan2(s[1], s[0])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## 向量加\n",
    "\n",
    "\\begin{equation}\\vec{v} = \\begin{bmatrix}2 \\\\ 1 \\end{bmatrix}\\end{equation}\n",
    "\n",
    "\\begin{equation}\\vec{s} = \\begin{bmatrix}-3 \\\\ 2 \\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXYAAAEQCAYAAACk818iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAErdJREFUeJzt3X2MXXWdx/H317aAMKKY4rTQQgkgguUpMwEfEpwBdq1KMLKCq6xilk0l0Q0kmkUFd7NuxE2Mrpr1qVmJD7CMoGAVfILQEdjAaocF0oaHogiWsimk8jCYCJXv/nEv2QLTznTOuffc+7vvV3LD3Lnn/s73m0s+8+25554bmYkkqRwva7oASVK9DHZJKozBLkmFMdglqTAGuyQVxmCXpMI0FuwRcWlEbI2IDTWsdVxE3BoRGyPiroh4Tx01SlI/iqbOY4+Ik4Bp4DuZubLiWq8FMjM3RcQBwBRwZGY+XkOpktRXGpvYM/MmYNuOv4uIQyPiZxExFRE3R8Tr5rjWfZm5qf3zFmArsH/tRUtSH1jYdAEvsgY4rz15nwh8FTh5dxaIiBOAPYDfdKA+Sep5PRPsETEEvAm4KiKe//We7cfOAD49w9Mezsy37rDGUuC7wDmZ+VxnK5ak3tQzwU7rsNDjmXncix/IzKuBq3f15IjYF7gOuDgzb+tMiZLU+3rmdMfMfBJ4ICLOBIiWY+fy3IjYA7iG1huxV3WwTEnqeU2e7ngFcCtwRERsjohzgbOBcyPiTmAj8M45LncWcBLwwYi4o317yeQvSYOgsdMdJUmd0TOHYiRJ9WjkzdPFixfnihUrmth1JU8//TT77LNP02V0zaD1C/Y8KPq156mpqccyc9bP6DQS7CtWrGD9+vVN7LqSyclJxsbGmi6jawatX7DnQdGvPUfEg3PZzkMxklQYg12SCmOwS1JhDHZJKozBLkmFMdglqTAGuyQVxmCXpMIY7JJUGINdkgpjsEtSYQx2SSqMwS5Jhakc7BGxV0T8KiLujIiNEfHPdRQmSZqfOi7b+yfg5MycjohFwC0R8VO/UFqSmlE52LP13XrT7buL2je/b0+SGlLLd55GxAJgCjgM+EpmXjjDNquB1QDDw8MjExMTlffbbdPT0wwNDTVdRtcMWr9gz4OiX3seHx+fyszR2bar9cusI+JVwDXA32fmhp1tNzo6mn6DUu8btH7BngdFv/YcEXMK9lrPisnMx4FJYFWd60qS5q6Os2L2b0/qRMTLgVOBe6quK0manzrOilkKfLt9nP1lwJWZeW0N60qS5qGOs2LuAo6voRZJUg385KkkFcZgl6TCGOySVBiDXZIKY7BLUmEMdkkqjMEuSYUx2CWpMAa7JBXGYJekwhjsklQYg12SCmOwS1JhDHZJKozBLkmFMdglqTAGuyQVxmCXpMLU8Z2nmqdM+Pzn4ZWvhNNOg6VLm65IUgmc2BsUAeecA5dcAgccACeeCJ/5DGzY0Ap9SZoPg71h++8PP/oRDA3Br34FF18MRx8Nhx4KF1wAN94Izz7bdJWS+knlYI+I5RGxLiLujoiNEXF+HYUNkqOPhssvb03wz3vgAfjSl+CUU1rh/773wfe+B0891VydkvpDHRP7duCjmXkk8AbgwxFxVA3rDpTTT28dkpnJE0/A2rVw332wYEF365LUfyoHe2Y+kpm3t39+CrgbOLDquoPowgvh7LNnfuySS+BTn4K99+5uTZL6T2SN79JFxArgJmBlZj75osdWA6sBhoeHRyYmJmrbb7dMT08zNDTU0X1kwr33wtNPv/Sx/faDgw6ChV06l6kb/fYaex4M/drz+Pj4VGaOzrphZtZyA4aAKeCM2bYdGRnJfrRu3bqu7GfLlswDD8yEzGOPzdxvv9bPkLl4ceaVV3aljK7120vseTD0a8/A+pxDHtdyVkxELAJ+AFyemVfXseYgW7q0dUz95S+HM8+EjRtbx+ABHnsMzjqrdXv00WbrlNSb6jgrJoBvAndn5heqlySAkRH41rfgkENaQf/DH8Jll7UOxwBcdRUcdVTrv5K0ozom9jcD7wdOjog72re317DuwDvrLHj3u1s/R7TeWHV6lzSbOs6KuSUzIzOPyczj2ref1FGcYI89Xnjf6V3SbPzkaR9yepe0KwZ7H3N6lzQTg73POb1LejGDvRBO75KeZ7AXxOldEhjsRXJ6lwabwV4op3dpcBnshXN6lwaPwT4AnN6lwWKwDxCnd2kwGOwDxuldKp/BPqCc3qVyGewDbLbpffv2ZuuTND8Gu3Y6vW/c6PQu9SODXcDM0/v27R57l/qRwa4X2HF6X7Cg9TuPvUv9xWDXSzw/vb/+9Z45I/Ujg107tWiRZ85I/chg1y553rvUfwx2zYnnvUv9w2DXnDm9S/2hlmCPiEsjYmtEbKhjPfU2p/fCbd0K69bBH//YdCWap7om9m8Bq2paS33A6b0ATz0Ft93WeuHOPx9OOQVe85rWX+7f/x723rvpCjVPtQR7Zt4EbKtjLfUXp/c+sXkzXHEFfPKTrb/EhxwC++4Lb3wjPPggfPnLcOON8MQT8P3vwwc+0HTFqsBj7KrM6b0PDA21Avuzn4Uf/xh+97uXbrP33nDttfCud3W9PNUrMrOehSJWANdm5sqdPL4aWA0wPDw8MjExUct+u2l6epqhoaGmy+ia+fa7bRs89BD8+c+t+wsXwkEH/f9E38uKfo0zYdOm1iGYHUwvW8bQI4/A4YfDPvs0VFx39evrPD4+PpWZo7NumJm13IAVwIa5bDsyMpL9aN26dU2X0FVV+t2yJfP00zNbadK6nXlm5tat9dXXCUW+xn/6U+Y3vpF50EEvfEHat3Vf/GLm7bc3XWVX9evrDKzPOWSsh2LUER577wHPPANr1rQm8Q99qPXPKHjhVL5sGRxxBBx/fDM1qiPqOt3xCuBW4IiI2BwR59axrvqbx94bsrNAX74cvvY1WLu2df+ww+CWW2CvvZqrVR1R11kx783MpZm5KDOXZeY361hXZXB675LZAn3TJjjvPNhzT1i5Em6+GQ4+uNma1REeilFXOL130O4EOrTC/Je/hCVLmqtZHWWwq6uc3mu0u4H+vOXL4dWv7n696hqDXV3n9F7RfANdA8NgV2Oc3neTga45MtjVKKf3OTDQtZsMdvUEp/cZGOiaJ4NdPcPpvc1AV0UGu3rOwE7vBrpqYrCrJw3U9G6gq2YGu3pa0dO7ga4OMdjV84qb3g10dZjBrr7R99O7ga4uMdjVV/pyejfQ1WUGu/pSX0zvBroaYrCrb/Xs9G6gq2EGu/pez0zvBrp6hMGuIjQ6vRvo6jEGu4rS1endQFePMthVnI5P7wa6epzBrmLVPr0b6OoTBruKVsv0bqCrzxjsGgjzmt4NdPWpWoI9IlZFxL0RcX9EfLyONaW6zXl6N9DV5yoHe0QsAL4CvA04CnhvRBxVdV2pU3Y+vSd/eOgpA119r46J/QTg/sz8bWY+A0wA76xhXaljZp7eg0cfC9JAV5+LzKy2QMS7gVWZ+Xft++8HTszMj7xou9XAaoDh4eGRiYmJSvttwvT0NENDQ02X0TWD1O+2bfDww3DwgX9g34c3w5IlsHhx6y9A4QbpdX5ev/Y8Pj4+lZmjs223sIZ9zfR//kv+WmTmGmANwOjoaI6NjdWw6+6anJykH+uer0Hr99ln4b9uWcfYO94+UNP5oL3OUH7PdRyK2Qws3+H+MmBLDetKXbVoEa0JfYBCXWWqI9h/DRweEYdExB7AXwM/qmFdSdI8VD4Uk5nbI+IjwM+BBcClmbmxcmWSpHmp4xg7mfkT4Cd1rCVJqsZPnkpSYQx2SSqMwS5JhTHYJakwBrskFcZgl6TCGOySVBiDXZIKY7BLUmEMdkkqjMEuSYUx2CWpMAa7JBXGYJekwhjsklQYg12SCmOwS1JhDHZJKozBLkmFMdglqTAGuyQVplKwR8SZEbExIp6LiNG6ipIkzV/ViX0DcAZwUw21SJJqsLDKkzPzboCIqKcaSVJlHmOXpMJEZu56g4gbgCUzPHRRZq5tbzMJfCwz1+9indXAaoDh4eGRiYmJ+dbcmOnpaYaGhpouo2sGrV+w50HRrz2Pj49PZeas72fOeigmM0+to6DMXAOsARgdHc2xsbE6lu2qyclJ+rHu+Rq0fsGeB0XpPXsoRpIKU/V0x3dFxGbgjcB1EfHzesqSJM1X1bNirgGuqakWSVINPBQjSYUx2CWpMAa7JBXGYJekwhjsklQYg12SCmOwS1JhDHZJKozBLkmFMdglqTAGuyQVxmCXpMIY7JJUGINdkgpjsEtSYQx2SSqMwS5JhTHYJakwBrskFcZgl6TCGOySVBiDXZIKUynYI+JzEXFPRNwVEddExKvqKkySND9VJ/brgZWZeQxwH/CJ6iVJkqqoFOyZ+YvM3N6+exuwrHpJkqQqIjPrWSjix8D3MvOynTy+GlgNMDw8PDIxMVHLfrtpenqaoaGhpsvomkHrF+x5UPRrz+Pj41OZOTrbdrMGe0TcACyZ4aGLMnNte5uLgFHgjJzDX4rR0dFcv379bJv1nMnJScbGxpouo2sGrV+w50HRrz1HxJyCfeFsG2TmqbPs6BzgNOCUuYS6JKmzZg32XYmIVcCFwFsy84/1lCRJqqLqWTH/DrwCuD4i7oiIr9dQkySpgkoTe2YeVlchkqR6+MlTSSqMwS5JhTHYJakwBrskFcZgl6TCGOySVBiDXZIKY7BLUmEMdkkqjMEuSYUx2CWpMAa7JBXGYJekwhjsklQYg12SCmOwS1JhDHZJKozBLkmFMdglqTAGuyQVxmCXpMJUCvaI+JeIuCsi7oiIX0TEAXUVJkman6oT++cy85jMPA64FvjHGmqSJFVQKdgz88kd7u4DZLVyJElVRWa1LI6IzwAfAJ4AxjPz0Z1stxpYDTA8PDwyMTFRab9NmJ6eZmhoqOkyumbQ+gV7HhT92vP4+PhUZo7Ott2swR4RNwBLZnjoosxcu8N2nwD2ysx/mm2no6OjuX79+tk26zmTk5OMjY01XUbXDFq/YM+Dol97jog5BfvC2TbIzFPnuM//BK4DZg12SVLnVD0r5vAd7p4O3FOtHElSVbNO7LP414g4AngOeBA4r3pJkqQqKgV7Zv5VXYVIkurhJ08lqTAGuyQVxmCXpMIY7JJUGINdkgpjsEtSYQx2SSqMwS5JhTHYJakwBrskFcZgl6TCGOySVJjK36A0r51GPErrapD9ZjHwWNNFdNGg9Qv2PCj6teeDM3P/2TZqJNj7VUSsn8u3l5Ri0PoFex4UpffsoRhJKozBLkmFMdh3z5qmC+iyQesX7HlQFN2zx9glqTBO7JJUGINdkgpjsM9DRHwsIjIiFjddS6dFxOci4p6IuCsiromIVzVdU6dExKqIuDci7o+IjzddT6dFxPKIWBcRd0fExog4v+mauiEiFkTE/0TEtU3X0ikG+26KiOXAXwAPNV1Ll1wPrMzMY4D7gE80XE9HRMQC4CvA24CjgPdGxFHNVtVx24GPZuaRwBuADw9AzwDnA3c3XUQnGey779+AfwAG4l3nzPxFZm5v370NWNZkPR10AnB/Zv42M58BJoB3NlxTR2XmI5l5e/vnp2iF3YHNVtVZEbEMeAfwH03X0kkG+26IiNOBhzPzzqZracjfAj9tuogOORD4/Q73N1N4yO0oIlYAxwP/3WwlHfdFWoPZc00X0kkLmy6g10TEDcCSGR66CPgk8JfdrajzdtVzZq5tb3MRrX+6X97N2rooZvjdQPyrLCKGgB8AF2Tmk03X0ykRcRqwNTOnImKs6Xo6yWB/kcw8dabfR8TRwCHAnREBrUMSt0fECZn5v10ssXY76/l5EXEOcBpwSpb7wYfNwPId7i8DtjRUS9dExCJaoX55Zl7ddD0d9mbg9Ih4O7AXsG9EXJaZf9NwXbXzA0rzFBG/A0Yzsx+vEDdnEbEK+ALwlsx8tOl6OiUiFtJ6c/gU4GHg18D7MnNjo4V1ULQmlG8D2zLzgqbr6ab2xP6xzDyt6Vo6wWPsms2/A68Aro+IOyLi600X1AntN4g/Avyc1puIV5Yc6m1vBt4PnNx+be9oT7Pqc07sklQYJ3ZJKozBLkmFMdglqTAGuyQVxmCXpIoi4tKI2BoRG2pY67iIuLV9Yba7IuI9u72GZ8VIUjURcRIwDXwnM1dWXOu1QGbmpog4AJgCjszMx+e6hhO7JFWUmTcB23b8XUQcGhE/i4ipiLg5Il43x7Xuy8xN7Z+3AFuB/XenHi8pIEmdsQY4rz15nwh8FTh5dxaIiBOAPYDf7M7zDHZJqln7wmpvAq5qX1sKYM/2Y2cAn57haQ9n5lt3WGMp8F3gnMzcratRGuySVL+XAY9n5nEvfqB9sbVdXnAtIvYFrgMuzszb5rNzSVKN2pc/fiAizoTWBdci4ti5PDci9gCuofVG7FXz2b/BLkkVRcQVwK3AERGxOSLOBc4Gzo2IO4GNzP0buc4CTgI+uMPF2V4y+e+yHk93lKSyOLFLUmEMdkkqjMEuSYUx2CWpMAa7JBXGYJekwhjsklSY/wOwZ0Gj1tmZdwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "v = np.array([2,1])\n",
    "s = np.array([-3,2])\n",
    "\n",
    "vecs = np.array([v,s])\n",
    "origin = [0], [0]\n",
    "plt.axis('equal')\n",
    "plt.grid()\n",
    "plt.ticklabel_format(style='sci', axis='both', scilimits=(0,0))\n",
    "plt.quiver(*origin, vecs[:,0], vecs[:,1], color=['r', 'b'], scale=10)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "\\begin{equation}\\vec{z} = \\vec{v}+\\vec{s}\\end{equation}\n",
    "\n",
    "\\begin{equation}\\vec{z} = \\begin{bmatrix}2 \\\\ 1 \\end{bmatrix} + \\begin{bmatrix}-3 \\\\ 2 \\end{bmatrix}\\end{equation}\n",
    "\n",
    "\\begin{equation}\\vec{z} = \\begin{bmatrix}2 \\\\ 1 \\end{bmatrix} + \\begin{bmatrix}-3 \\\\ 2 \\end{bmatrix} = \\begin{bmatrix}-1 \\\\ 3 \\end{bmatrix}\\end{equation}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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E5k5POuBmVnJDRgEJoALZzt27dq12USbNm3qynm2b8887rhMyFyzJvOoo1r3IXPp0syvfa0rZXRtvwt18udOTj5OrrlqTWVr9vqeO8E9NwewOeeQx5VcFRMRi4G/A67OzGurWLOfHXNMa6Z+2GGwbh1MTrZm8ACPPAIXXdS67dxZb511cxwjzayKq2IC+Evg3sz84/ZLEsDatfDlL8MJJ7SC/u//Hr7yldY4BmDjRli1qvXffuXVMdLMqujYXw+8AzgnIu6avr2xgnX73kUXwVvf2rof0Xpj1e79eV4dI82siqtivpOZkZmnZebp07evV1Gc4JBDXvjY7v2FHMdI+/M3TxvI7v15jmOk/RnsDWb37jhGmonB3nB2745jpBcz2AvRz9274xjphQz2gvRr9+44Rnohg71A/di9O46RnmewF6rfunfHMdLzDPbC9Uv37jhGep7B3gf6pXt3HCO1GOx9pPTu3XGM1GKw95mSu3fHMVKLwd6nSu3eHcdIBntfm61737u33voWwnGMZLCLA3fvk5PN694dx0gGu6bN1L3v3dvM2bvjGPU7g10vsG/3vmhR62tNm707jlG/M9i1n+e691NOaeaVM45j1O8Mdh3Q4sXNvXLGcYz6mcGug2rqde+OY9TPDHbNSdOue3cco35msGvOmta9O45Rv6ok2CPiSxGxIyLuqWI99bamdO+OYxZoxw7YtAl+9rO6K9ECVdWxfxk4v6K11ABN6N4dx8zi8cfhjjtaL9zll8O558LLX976yf3gg3D44XVXqAWqJNgz8zZgVxVrqVl6vXt3HDNt2za45hr48IdbP4lPOAGOPBJe9zr48Y/hz/4MvvUteOwx+Nu/hXe+s+6K1QZn7GpbL3fvjmOmDQ62AvsP/gBuvBF+9KP9jzn8cLjpJnjLW7penqoVmVnNQhErgZsyc/UBnl8PrAcYGhpaOzY2Vsl5u2lqaorBwcG6y+iahe531y74yU/gmWdajwcG4Pjjn+/ou21y5yRP7H2CwwYOY9XRqw56bNGvcSbcf39rBLOPqeXLGXz4YTjxRDjiiJqK666mvs6jo6MTmTk864GZWckNWAncM5dj165dm020adOmukvoqnb2u3175gUXZLbSpHVbty5zx47q6purj236WPJxko+T9z1y30GPLfI1fvLJzC98IfP441/4gkzfNn32s5l33ll3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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "z = v + s\n",
    "vecs = np.array([v,s,z])\n",
    "origin = [0], [0]\n",
    "plt.axis('equal')\n",
    "plt.grid()\n",
    "plt.ticklabel_format(style='sci', axis='both', scilimits=(0,0))\n",
    "plt.quiver(*origin, vecs[:,0], vecs[:,1], color=['r', 'b', 'g'], scale=10)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "# 向量乘\n",
    "\n",
    "向量乘有三种\n",
    "\n",
    "- 标量乘\n",
    "- 点积\n",
    "- 叉积\n",
    "\n",
    "## 标量乘\n",
    "\n",
    "\n",
    "\\begin{equation} \\vec{w} = 2\\vec{v}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}\\vec{v} = \\begin{bmatrix}2 \\\\ 1 \\end{bmatrix}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}\\vec{w} = \\begin{bmatrix}2 \\cdot 2 \\\\  2 \\cdot 1 \\end{bmatrix}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}\\vec{w} = \\begin{bmatrix}2 \\cdot 2 \\\\  2 \\cdot 1 \\end{bmatrix} = \\begin{bmatrix}4 \\\\ 2 \\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "v = np.array([2,1])\n",
    "\n",
    "w = 2 * v\n",
    "\n",
    "origin = [0], [0]\n",
    "plt.grid()\n",
    "plt.ticklabel_format(style='sci', axis='both', scilimits=(0,0))\n",
    "plt.quiver(*origin, *w, scale=10)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "乘以一个分数就是标量除\n",
    "\n",
    "\\begin{equation}\\vec{b} = \\frac{\\vec{v}}{2}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "b = v / 2\n",
    "\n",
    "origin = [0], [0]\n",
    "plt.axis('equal')\n",
    "plt.grid()\n",
    "plt.ticklabel_format(style='sci', axis='both', scilimits=(0,0))\n",
    "plt.quiver(*origin, *b, scale=10)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## 点乘（内积）\n",
    "\n",
    "- 点乘的结果是一个标量\n",
    "- 叉乘的结果是一个向量\n",
    "\n",
    "\n",
    "\\begin{equation} \\vec{v} \\cdot \\vec{s} = (v_{1} \\cdot s_{1}) + (v_{2} \\cdot s_{2}) ... + \\; (v_{n} \\cdot s_{n})\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation} \\vec{v} \\cdot \\vec{s} = (2 \\cdot -3) + (1 \\cdot 2) = -6 + 2 = -4\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-4\n",
      "-4\n"
     ]
    }
   ],
   "source": [
    "v = np.array([2,1])\n",
    "s = np.array([-3,2])\n",
    "d = np.dot(v,s)             # 方法名是 dot\n",
    "print(d)\n",
    "print(v @ s)                # 或者直接用 @ 操作符"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 用点乘计算向量的余弦\n",
    "\n",
    "\n",
    "$$ \\vec{v} \\cdot \\vec{s} = \\|\\vec{v} \\|\\|\\vec{s}\\| \\cos (\\theta) $$ \n",
    "\n",
    "\n",
    "$$ \\cos(\\theta) = \\frac{\\vec{v} \\cdot \\vec{s}}{\\|\\vec{v} \\|\\|\\vec{s}\\|} $$\n",
    "\n",
    "\n",
    "$$ \\cos(\\theta) = \\frac{(2 \\cdot-3) + (-3 \\cdot 2)}{\\sqrt{2^{2} + 1^{2}} \\times \\sqrt{-3^{2} + 2^{2}}} $$\n",
    "\n",
    "\n",
    "$$\\cos(\\theta) = \\frac{-4}{8.0622577483}$$\n",
    "\n",
    "\n",
    "$$\\cos(\\theta) = -0.496138938357 $$\n",
    "\n",
    "$$\\theta \\approx 119.74 $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "119.74488129694222"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v = np.array([2,1])\n",
    "s = np.array([-3,2])\n",
    "\n",
    "vMag = np.linalg.norm(v)               # 计算标量\n",
    "sMag = np.linalg.norm(s)\n",
    "\n",
    "cos = (v @ s) / (vMag * sMag)          # 点乘除标量积是余弦\n",
    "\n",
    "theta = math.degrees(math.acos(cos))\n",
    "\n",
    "theta"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## 叉乘（外积）\n",
    "\n",
    "\n",
    "\\begin{equation}\\vec{p} = \\begin{bmatrix}2 \\\\ 3 \\\\ 1 \\end{bmatrix}\\;\\; \\vec{q} = \\begin{bmatrix}1 \\\\ 2 \\\\ -2 \\end{bmatrix}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}r_{1} = p_{2}q_{3} - p_{3}q_{2}\\end{equation}\n",
    "\\begin{equation}r_{2} = p_{3}q_{1} - p_{1}q_{3}\\end{equation}\n",
    "\\begin{equation}r_{3} = p_{1}q_{2} - p_{2}q_{1}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}\\vec{r} = \\vec{p} \\times \\vec{q} = \\begin{bmatrix}(3 \\cdot -2) - (1 \\cdot 2) \\\\ (1 \\cdot 1) - (2 \\cdot -2) \\\\ (2 \\cdot 2) - (3 \\cdot 1) \\end{bmatrix} = \\begin{bmatrix}-6 - 2 \\\\ 1 - -4 \\\\ 4 - 3 \\end{bmatrix} = \\begin{bmatrix}-8 \\\\ 5 \\\\ 1 \\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-8,  5,  1])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p = np.array([2,3,1])\n",
    "q = np.array([1,2,-2])\n",
    "r = np.cross(p,q)\n",
    "r"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 理解向量外积\n",
    "\n",
    "- 只知道定义和方法cross是不够的\n",
    "- 应用场景：求共点向量的法向量\n",
    "- 需要三维可视化\n",
    "\n",
    "> 编程实现！"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "from mpl_toolkits.mplot3d import Axes3D\n",
    "\n",
    "def vec3d_range(m):\n",
    "    a = [(min(0,m[:,i].min()), m[:,i].max()) for i in [0, 1, 2]]\n",
    "    return np.array(a) * 1.2\n",
    "\n",
    "def vec3d_label(v):\n",
    "    return '(' + ','.join(str(i) for i in v) + ')'\n",
    "    \n",
    "def vec3d_cord(m):\n",
    "    return zip(*np.concatenate((np.zeros(m.shape), m), axis=1))\n",
    "\n",
    "def vec3d_color(m):\n",
    "    l = np.random.rand(*m.shape)\n",
    "    return [*l, *[i for s in [*zip(l,l)] for i in s]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.core.interactiveshell import InteractiveShell\n",
    "InteractiveShell.ast_node_interactivity = \"last_expr\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "d60721c46aa74580913611c22cd0f805",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "FigureCanvasNbAgg()"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib widget\n",
    "\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt3d\n",
    "\n",
    "p, q, r = [[2, 3, 1], [1, 2, -1], [-8, 5, 1]]\n",
    "m = np.array([p,q,r])\n",
    "ax = plt3d.axes(projection='3d')\n",
    "ax.set_xlabel('X')\n",
    "ax.set_ylabel('Y')\n",
    "ax.set_zlabel('Z')\n",
    "rx, ry, rz = vec3d_range(m)\n",
    "ax.set_xlim(rx)\n",
    "ax.set_ylim(ry)\n",
    "ax.set_zlim(rz)\n",
    "ax.quiver(*vec3d_cord(m), arrow_length_ratio=0.1, color=vec3d_color(m))\n",
    "[ax.text(*v, vec3d_label(v), tuple(v)) for v in [p, q, r]]\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "- 3D绘制的帮助函数\n",
    "\n",
    "```python\n",
    "def vec3d_range(m):\n",
    "    a = [(min(0,m[:,i].min()), m[:,i].max()) for i in [0, 1, 2]]\n",
    "    return np.array(a) * 1.2\n",
    "def vec3d_label(v):\n",
    "    return '(' + ','.join(str(i) for i in v) + ')'\n",
    "def vec3d_cord(m):\n",
    "    return zip(*np.concatenate((np.zeros(m.shape), m), axis=1))\n",
    "def vec3d_color(m):\n",
    "    l = np.random.rand(*m.shape)\n",
    "    return [*l, *[i for s in [*zip(l,l)] for i in s]]\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "- 很多时候文档可以帮助了解接口（目的）\n",
    "- 需要运行代码来深入理解实现（测试即文档）\n",
    "- 经过训练，人脑也可以运行代码（仔细阅读）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# 矩阵\n",
    "\n",
    "\n",
    "- 矩阵的记法\n",
    "\n",
    "\\begin{equation}A = \\begin{bmatrix}\n",
    "  1 & 2 & 3 \\\\\n",
    "  4 & 5 & 6\n",
    " \\end{bmatrix}\n",
    "\\end{equation}\n",
    "\n",
    "- 矩阵的下标\n",
    "\n",
    "\\begin{equation}A = \\begin{bmatrix}\n",
    "  a_{1,1} & a_{1,2} & a_{1,3} \\\\\n",
    "  a_{2,1} & a_{2,2} & a_{2,3}\n",
    " \\end{bmatrix}\n",
    "\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]]\n",
      "[[1 2 3]\n",
      " [4 5 6]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1,2,3],\n",
    "              [4,5,6]])\n",
    "print(A)\n",
    "M = np.matrix([[1,2,3],        # 也可以用matrix，它是array的子类\n",
    "               [4,5,6]])\n",
    "print(M)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 向量加\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}1 & 2 & 3 \\\\4 & 5 & 6\\end{bmatrix}+ \\begin{bmatrix}6 & 5 & 4 \\\\3 & 2 & 1\\end{bmatrix} = \\begin{bmatrix}7 & 7 & 7 \\\\7 & 7 & 7\\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[7 7 7]\n",
      " [7 7 7]]\n",
      "[[7 7 7]\n",
      " [7 7 7]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1,2,3],\n",
    "              [4,5,6]])\n",
    "B = np.array([[6,5,4],\n",
    "              [3,2,1]])\n",
    "print(A + B)                            # + 操作符\n",
    "print(np.add(A, B))                     # add方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 向量减\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}1 & 2 & 3 \\\\4 & 5 & 6\\end{bmatrix}- \\begin{bmatrix}6 & 5 & 4 \\\\3 & 2 & 1\\end{bmatrix} = \\begin{bmatrix}-5 & -3 & -1 \\\\1 & 3 & 5\\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[-5 -3 -1]\n",
      " [ 1  3  5]]\n",
      "[[-5 -3 -1]\n",
      " [ 1  3  5]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1,2,3],\n",
    "              [4,5,6]])\n",
    "B = np.array([[6,5,4],\n",
    "              [3,2,1]])\n",
    "print (A - B)                           # - 操作符\n",
    "print(np.subtract(A, B))                # subtract方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 求负\n",
    "\n",
    "\\begin{equation}C = \\begin{bmatrix}-5 & -3 & -1 \\\\1 & 3 & 5\\end{bmatrix}\\end{equation}\n",
    "\n",
    "\\begin{equation}-C = \\begin{bmatrix}5 & 3 & 1 \\\\-1 & -3 & -5\\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 5  3  1]\n",
      " [-1 -3 -5]]\n",
      "[[ 5  3  1]\n",
      " [-1 -3 -5]]\n"
     ]
    }
   ],
   "source": [
    "C = np.array([[-5,-3,-1],\n",
    "              [1,3,5]])\n",
    "print(-C)                               # - 这里是一元的操作符，和减法（二元的操作符）是不同的\n",
    "print(np.negative(C))                   # negative方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 矩阵转置\n",
    "\\begin{equation}\\begin{bmatrix}1 & 2 & 3 \\\\4 & 5 & 6\\end{bmatrix}^{T} = \\begin{bmatrix}1 & 4\\\\2 & 5\\\\3 & 6 \\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 4]\n",
      " [2 5]\n",
      " [3 6]]\n",
      "[[1 4]\n",
      " [2 5]\n",
      " [3 6]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1,2,3],\n",
    "              [4,5,6]])\n",
    "print(A.T)                             # T 简写\n",
    "print(np.transpose(A))                 # transpose方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 矩阵乘\n",
    "\n",
    "简单情况：矩阵乘以标量\n",
    "\n",
    "\\begin{equation}2 \\times \\begin{bmatrix}1 & 2 & 3 \\\\4 & 5 & 6\\end{bmatrix} = \\begin{bmatrix}2 & 4 & 6 \\\\8 & 10 & 12\\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 2,  4,  6],\n",
       "       [ 8, 10, 12]])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = np.array([[1,2,3],\n",
    "              [4,5,6]])\n",
    "2 * A"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 矩阵相乘\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}1 & 2 & 3 \\\\4 & 5 & 6\\end{bmatrix} \\cdot \\begin{bmatrix}9 & 8 \\\\ 7 & 6 \\\\ 5 & 4\\end{bmatrix}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}(1,2,3) \\cdot (9,7,5) = (1 \\times 9) + (2 \\times 7) + (3 \\times 5) = 38\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}38 & ?\\\\? & ?\\end{bmatrix} \\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}(1,2,3) \\cdot (8,6,4) = (1 \\times 8) + (2 \\times 6) + (3 \\times 4) = 32\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}38 & 32\\\\? & ?\\end{bmatrix} \\end{equation}\n",
    "\n",
    "\n",
    "\n",
    "\\begin{equation}(4,5,6) \\cdot (9,7,5) = (4 \\times 9) + (5 \\times 7) + (6 \\times 5) = 101\\end{equation}\n",
    "\n",
    "\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}38 & 32\\\\101 & ?\\end{bmatrix} \\end{equation}\n",
    "\n",
    "\n",
    "\n",
    "\\begin{equation}(4,5,6) \\cdot (8,6,4) = (4 \\times 8) + (5 \\times 6) + (6 \\times 4) = 86\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}38 & 32\\\\101 & 86\\end{bmatrix} \\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, 3) (3, 2)\n",
      "[[ 38  32]\n",
      " [101  86]]\n",
      "[[ 38  32]\n",
      " [101  86]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1,2,3],\n",
    "              [4,5,6]])\n",
    "B = np.array([[9,8],\n",
    "              [7,6],\n",
    "              [5,4]])\n",
    "print(A.shape, B.shape)\n",
    "print(np.dot(A,B))\n",
    "print(A @ B)                    # @ 代表点乘（内积）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 38  32]\n",
      " [101  86]]\n",
      "[1 2 3] (3,) [9 7 5] (3,)\n",
      "[ 9 14 15] 38\n"
     ]
    }
   ],
   "source": [
    "A = np.matrix([[1,2,3]\n",
    "               ,[4,5,6]])\n",
    "B = np.matrix([[9,8],\n",
    "               [7,6],\n",
    "               [5,4]])\n",
    "print(A * B)                                    # * 操作符也是可以的，但是注意：不要用在向量上\n",
    "line = np.array(A)[0]\n",
    "column = np.array(B)[:,0]\n",
    "print(line, line.shape, column, column.shape)   # 取出第一行和第一列\n",
    "print(line * column, line @ column)             # 对于向量，* 和 @ 完全不同"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "矩阵相乘没有交换律\n",
    "\\begin{equation}2 \\times 4 = 4 \\times 2\\end{equation}\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}2 & 4 \\\\6 & 8\\end{bmatrix} \\cdot \\begin{bmatrix}1 & 3 \\\\ 5 & 7\\end{bmatrix} \\ne \\begin{bmatrix}1 & 3 \\\\ 5 & 7\\end{bmatrix} \\cdot \\begin{bmatrix}2 & 4 \\\\6 & 8\\end{bmatrix}\\end{equation}\n",
    "\n",
    "可以想像一个3x2的矩阵乘以一个2x3的矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[22 34]\n",
      " [46 74]]\n",
      "[[20 28]\n",
      " [52 76]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[2,4],\n",
    "              [6,8]])\n",
    "B = np.array([[1,3],\n",
    "              [5,7]])\n",
    "print(A @ B)\n",
    "print(B @ A)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## 单位矩阵\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}1 & 0 & 0\\\\0 & 1 & 0\\\\0 & 0 & 1\\end{bmatrix} \\end{equation}\n",
    "\n",
    "\n",
    "乘以单位矩阵还是矩阵本身\n",
    "\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}1 & 2 & 3 \\\\4 & 5 & 6\\\\7 & 8 & 9\\end{bmatrix} \\cdot \\begin{bmatrix}1 & 0 & 0\\\\0 & 1 & 0\\\\0 & 0 & 1\\end{bmatrix} = \\begin{bmatrix}1 & 2 & 3 \\\\4 & 5 & 6\\\\7 & 8 & 9\\end{bmatrix} \\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1,2,3],\n",
    "              [4,5,6],\n",
    "              [7,8,9]])\n",
    "B = np.array([[1,0,0],\n",
    "              [0,1,0],\n",
    "              [0,0,1]])\n",
    "print(A @ B)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## 逆矩阵\n",
    "\n",
    "\\begin{equation}A \\div B = A \\cdot B^{-1}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}B \\cdot B^{-1} = B^{-1} \\cdot B = I\\end{equation}\n",
    "\n",
    "**I** 是单位矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0.2 -0.2]\n",
      " [-0.1  0.6]]\n",
      "[[ 0.2 -0.2]\n",
      " [-0.1  0.6]]\n"
     ]
    }
   ],
   "source": [
    "B = np.array([[6,2],\n",
    "              [1,2]])\n",
    "\n",
    "print(np.linalg.inv(B))    # 矩阵求逆\n",
    "print(np.matrix(B).I)      # 简写，参考转置"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## 解方程组\n",
    "\n",
    "\\begin{equation}2x + 4y = 18\\end{equation}\n",
    "\\begin{equation}6x + 2y = 34\\end{equation}\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}2 & 4\\\\6 & 2\\end{bmatrix} \\cdot \\begin{bmatrix}x\\\\y\\end{bmatrix}=\\begin{bmatrix}18\\\\34\\end{bmatrix}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}A=\\begin{bmatrix}2 & 4\\\\6 & 2\\end{bmatrix}\\;\\;\\;\\;X=\\begin{bmatrix}x\\\\y\\end{bmatrix}\\;\\;\\;\\;B=\\begin{bmatrix}18\\\\34\\end{bmatrix}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}2 & 4\\\\6 & 2\\end{bmatrix}^{-1} = \\begin{bmatrix}-0.1 & 0.2\\\\0.3 & -0.1\\end{bmatrix}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}X = \\begin{bmatrix}-0.1 & 0.2\\\\0.3 & -0.1\\end{bmatrix} \\cdot \\begin{bmatrix}18\\\\34\\end{bmatrix}\\end{equation}\n",
    "\n",
    "\n",
    "\\begin{equation}X = \\begin{bmatrix}5\\\\2\\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[5.]\n",
      " [2.]]\n",
      "[[5.]\n",
      " [2.]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[2,4],\n",
    "              [6,2]])\n",
    "\n",
    "B = np.array([[18],\n",
    "              [34]])\n",
    "\n",
    "C = np.linalg.inv(A) @ B\n",
    "\n",
    "print(C)\n",
    "print(np.linalg.solve(A, B))             # 调用方法solve，在Numpy介绍中提到过"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# 变换，特征向量和特征值\n",
    "\n",
    "\n",
    "\n",
    "## 线性变换\n",
    "\n",
    "\n",
    "对矩阵 ***A*** 和向量 ***v***:\n",
    "\n",
    "$$ A = \\begin{bmatrix}2 & 3\\\\5 & 2\\end{bmatrix} \\;\\;\\;\\; \\vec{v} = \\begin{bmatrix}1\\\\2\\end{bmatrix}$$\n",
    "\n",
    "定义 ***T*** 为:\n",
    "\n",
    "$$ T(\\vec{v}) = A\\vec{v} $$\n",
    "\n",
    "向量和矩阵的点乘是和右侧矩阵的每一列做向量点乘，最后得到一个变换后的向量\n",
    "\n",
    "$$\\begin{bmatrix}2 & 3\\\\5 & 2\\end{bmatrix} \\cdot  \\begin{bmatrix}1\\\\2\\end{bmatrix} = \\begin{bmatrix}8\\\\9\\end{bmatrix}$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[8 9]\n"
     ]
    }
   ],
   "source": [
    "v = np.array([1,2])\n",
    "A = np.array([[2,3],\n",
    "              [5,2]])\n",
    "\n",
    "t = A@v\n",
    "print (t)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "可见变换T是一个从二维实数向量向另一个二维实数向量的变换: ${\\rm I\\!R^{2} \\to \\rm I\\!R^{2} }$\n",
    "\n",
    "\n",
    "输出向量的维度可以和原向量不同，因此准确地说：${\\rm I\\!R^{n} \\to \\rm I\\!R^{m}}$\n",
    "\n",
    "比如\n",
    "\n",
    "$$ A = \\begin{bmatrix}2 & 3\\\\5 & 2\\\\1 & 1\\end{bmatrix} \\;\\;\\;\\; \\vec{v} = \\begin{bmatrix}1\\\\2\\end{bmatrix}$$\n",
    "\n",
    "$$ T(\\vec{v}) = A\\vec{v} $$\n",
    "\n",
    "$$\\begin{bmatrix}2 & 3\\\\5 & 2\\\\1 & 1\\end{bmatrix} \\cdot  \\begin{bmatrix}1\\\\2\\end{bmatrix} = \\begin{bmatrix}8\\\\9\\\\3\\end{bmatrix}$$\n",
    "\n",
    "所以${ T: \\rm I\\!R^{2} \\to \\rm I\\!R^{3} }$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[8 9 3]\n"
     ]
    }
   ],
   "source": [
    "v = np.array([1,2])\n",
    "A = np.array([[2,3],\n",
    "              [5,2],\n",
    "              [1,1]])\n",
    "\n",
    "t = A@v                   # (2) → (3)\n",
    "print (t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[5 4]\n"
     ]
    }
   ],
   "source": [
    "v = np.array([1,2])\n",
    "A = np.array([[1,2],\n",
    "              [2,1]])\n",
    "\n",
    "t = A@v                   # (2) → (2)\n",
    "print (t)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## 向量的缩放和旋转变换\n",
    "\n",
    "\n",
    "$$ A = \\begin{bmatrix}2 & 0\\\\0 & 2\\end{bmatrix} \\;\\;\\;\\; \\vec{v} = \\begin{bmatrix}1\\\\0\\end{bmatrix}$$\n",
    "\n",
    "缩放变换的例子：\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}2 & 0\\\\0 & 2\\end{bmatrix} \\cdot  \\begin{bmatrix}1\\\\0\\end{bmatrix} = \\begin{bmatrix}2\\\\0\\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "旋转90°的变换\n",
    "\\begin{equation}\\begin{bmatrix}0 & -1\\\\1 & 0\\end{bmatrix} \\cdot  \\begin{bmatrix}1\\\\0\\end{bmatrix} = \\begin{bmatrix}0\\\\1\\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "v = np.array([1,0])\n",
    "A = np.array([[0,-1],\n",
    "              [1,0]])\n",
    "\n",
    "t = A@v\n",
    "\n",
    "vecs = np.array([v,t])\n",
    "origin = [0], [0]\n",
    "plt.axis('equal')\n",
    "plt.grid()\n",
    "plt.ticklabel_format(style='sci', axis='both', scilimits=(0,0))\n",
    "plt.quiver(*origin, vecs[:,0], vecs[:,1], color=['orange', 'blue'], scale=10)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "变换\n",
    "\\begin{equation}\\begin{bmatrix}2 & 1\\\\1 & 2\\end{bmatrix} \\cdot  \\begin{bmatrix}1\\\\0\\end{bmatrix} = \\begin{bmatrix}2\\\\1\\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "v = np.array([1,0])\n",
    "A = np.array([[2,1],                       # 旋转 + 缩放\n",
    "              [1,2]])\n",
    "\n",
    "t = A@v\n",
    "\n",
    "vecs = np.array([v,t])\n",
    "origin = [0], [0]\n",
    "plt.axis('equal')\n",
    "plt.grid()\n",
    "plt.ticklabel_format(style='sci', axis='both', scilimits=(0,0))\n",
    "plt.quiver(*origin, vecs[:,0], vecs[:,1], color=['orange', 'blue'], scale=10)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 线性变换的几何解释\n",
    "\n",
    "- 缩放: ${a \\cdot I \\cdot \\vec{v}}$\n",
    "- 旋转: ${\\vec{v} \\cdot T}$\n",
    "- 平移: ${\\vec{v} + \\vec{b}}$\n",
    "\n",
    "在二维平面上可以定义旋转矩阵${T}$为：\n",
    "$$T = \\begin{bmatrix}\\cos{\\theta} & -\\sin{\\theta}\\\\ \\sin{\\theta} & \\cos{\\theta} \\end{bmatrix}$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "cos, sin, pi = math.cos, math.sin, math.pi\n",
    "\n",
    "def rotate(a):\n",
    "    return np.array([[cos(a), -sin(a)],\n",
    "                   [sin(a),cos(a)]])\n",
    "\n",
    "v = np.array([1,0])\n",
    "alpha = pi/5                      # 旋转36°\n",
    "beta  = pi/4                      # 旋转45°\n",
    "gamma = pi/3                      # 旋转60°\n",
    "\n",
    "vecs = np.array([v, *[rotate(a)@v for a in [alpha, beta, gamma]]])\n",
    "origin = [0], [0]\n",
    "plt.axis('equal')\n",
    "plt.grid()\n",
    "plt.ticklabel_format(style='sci', axis='both', scilimits=(0,0))\n",
    "plt.quiver(*origin, vecs[:,0], vecs[:,1], color=['r', 'b', 'm', 'g'], scale=10)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 仿射变换\n",
    "\n",
    "$$T(\\vec{v}) = A\\vec{v} + \\vec{b}$$\n",
    "\n",
    "例如：\n",
    "\n",
    "\\begin{equation}\\begin{bmatrix}5 & 2\\\\3 & 1\\end{bmatrix} \\cdot  \\begin{bmatrix}1\\\\1\\end{bmatrix} + \\begin{bmatrix}-2\\\\-6\\end{bmatrix} = \\begin{bmatrix}5\\\\-2\\end{bmatrix}\\end{equation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "v = np.array([1,1])\n",
    "A = np.array([[5,2],\n",
    "              [3,1]])\n",
    "b = np.array([-2,-6])\n",
    "\n",
    "t = A@v + b\n",
    "\n",
    "vecs = np.array([v,t])\n",
    "origin = [0], [0]\n",
    "plt.axis('equal')\n",
    "plt.grid()\n",
    "plt.ticklabel_format(style='sci', axis='both', scilimits=(0,0))\n",
    "plt.quiver(*origin, vecs[:,0], vecs[:,1], color=['orange', 'blue'], scale=15)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## 特征向量和特征值 \n",
    "\n",
    "变换 ${\\begin{bmatrix}2 & 0\\\\0 & 2\\end{bmatrix} \\cdot  \\begin{bmatrix}1\\\\0\\end{bmatrix} = \\begin{bmatrix}2\\\\0\\end{bmatrix}}$ 等价于 ${2 \\times \\begin{bmatrix}1\\\\0\\end{bmatrix} = \\begin{bmatrix}2\\\\0\\end{bmatrix}}$，也可记作${ T(\\vec{v}) = \\lambda\\vec{v}}$，其中\n",
    "\n",
    "$$ T(\\vec{v}) = A\\vec{v} = \\lambda\\vec{v}$$\n",
    "\n",
    "则称 ${\\vec{v}}$ 和 ${\\lambda}$ 是 ${A}$ 的特征向量和特征值。\n",
    "\n",
    "假设，${A=\\begin{bmatrix}2 & 0\\\\0 & 3\\end{bmatrix}}$, 下面求 ${A}$ 的特征向量和特征值："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    ">[特征值](https://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.eig.html?highlight=eig#numpy.linalg.eig)文档\n",
    "\n",
    "![特征值](http://bazhou.blob.core.windows.net/learning/mpp/eig.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2. 3.]\n",
      "[[1. 0.]\n",
      " [0. 1.]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[2,0],\n",
    "              [0,3]])\n",
    "eVals, eVecs = np.linalg.eig(A)\n",
    "print(eVals)\n",
    "print(eVecs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "特征值和特征向量是成对出现的：\n",
    "$$ \\bigg( \\lambda_{1} = 2, \\;\\; \\vec{v_{1}} = \\begin{bmatrix}1 \\\\ 0\\end{bmatrix} \\bigg) \\;\\;\\; 和\\;\\;\\; \\bigg( \\lambda_{2} = 3, \\;\\; \\vec{v_{2}} = \\begin{bmatrix}0 \\\\ 1\\end{bmatrix} \\bigg) $$\n",
    "\n",
    "可以验证，特征值乘相应的特征向量等于矩阵点乘特征向量 \n",
    "\n",
    "$$ 2 \\times \\begin{bmatrix}1 \\\\ 0\\end{bmatrix} = \\begin{bmatrix}2 \\\\ 0\\end{bmatrix}  \\Leftrightarrow \\begin{bmatrix}2 & 0\\\\0 & 3\\end{bmatrix} \\cdot \\begin{bmatrix}1 \\\\ 0\\end{bmatrix} = \\begin{bmatrix}2 \\\\ 0\\end{bmatrix} $$ \n",
    "\n",
    "以及\n",
    "\n",
    "$$ 3 \\times \\begin{bmatrix}0 \\\\ 1\\end{bmatrix} = \\begin{bmatrix}0 \\\\ 3\\end{bmatrix}  \\Leftrightarrow \\begin{bmatrix}2 & 0\\\\0 & 3\\end{bmatrix} \\cdot \\begin{bmatrix}0 \\\\ 1\\end{bmatrix} = \\begin{bmatrix}0 \\\\ 3\\end{bmatrix} $$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "练习：\n",
    "\n",
    "求矩阵 ${\\begin{bmatrix}2 & 1\\\\1 & 2\\end{bmatrix}}$ 的特征值和特征向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3. 1.] [[ 0.70710678 -0.70710678]\n",
      " [ 0.70710678  0.70710678]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[array([ True,  True]), array([ True,  True])]"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = np.array([[2,1],\n",
    "              [1,2]])\n",
    "\n",
    "eVals, eVecs = np.linalg.eig(A)\n",
    "print(eVals, eVecs)                                        # 注意取eVecs的列\n",
    "[A @ eVecs[:,i] == eVals[i] * eVecs[:,i] for i in [0, 1]]  # 向量的 == 操作\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "$$ \\bigg( \\lambda_{1} = 3, \\;\\; \\vec{v_{1}} = \\begin{bmatrix}0.70710678 \\\\ 0.70710678\\end{bmatrix} \\bigg) \\;\\;\\;和\\;\\;\\; \\bigg( \\lambda_{2} = 1, \\;\\; \\vec{v_{2}} = \\begin{bmatrix}-0.70710678 \\\\ 0.70710678\\end{bmatrix} \\bigg) $$\n",
    "\n",
    "$$ 3 \\times \\begin{bmatrix}0.70710678 \\\\ 0.70710678\\end{bmatrix} = \\begin{bmatrix}2.12132034 \\\\ 2.12132034\\end{bmatrix}  \\Leftrightarrow \\begin{bmatrix}2 & 1\\\\1 & 2\\end{bmatrix} \\cdot \\begin{bmatrix}0.70710678 \\\\ 0.70710678\\end{bmatrix} = \\begin{bmatrix}2.12132034 \\\\ 2.12132034\\end{bmatrix} $$\n",
    "\n",
    "和\n",
    "\n",
    "$$ 1 \\times \\begin{bmatrix}-0.70710678 \\\\ 0.70710678\\end{bmatrix} = \\begin{bmatrix}-0.70710678\\\\0.70710678\\end{bmatrix}  \\Leftrightarrow \\begin{bmatrix}2 & 1\\\\1 & 2\\end{bmatrix} \\cdot \\begin{bmatrix}-0.70710678 \\\\ 0.70710678\\end{bmatrix} = \\begin{bmatrix}-0.70710678\\\\0.70710678\\end{bmatrix} $$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## 特征分解\n",
    "\n",
    "从前面的例子可以推导出下面的等式：\n",
    "\n",
    "$$A = Q \\Lambda Q^{-1}$$\n",
    "\n",
    "（可以理解为变换到特征向量定义的空间上，投影值就是特征值，然后再变换回来）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0.96276969 -0.48963374]\n",
      " [ 0.27032301  0.87192821]]\n",
      "[[ 3.56155281  0.        ]\n",
      " [ 0.         -0.56155281]]\n",
      "[[ 0.96276969 -0.48963374]\n",
      " [ 0.27032301  0.87192821]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[3,2],\n",
    "              [1,0]])\n",
    "\n",
    "l, Q = np.linalg.eig(A)\n",
    "L = np.diag(l)\n",
    "Qinv = np.linalg.inv(Q)\n",
    "print(Q)\n",
    "print(L)\n",
    "print(Q)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "计算${Q}$、${\\Lambda}$ 和 ${Q^{-1}}$\n",
    "$$Q=\\begin{bmatrix}0.96276969 & -0.48963374\\\\0.27032301 & 0.87192821\\end{bmatrix}$$\n",
    "\n",
    "$$\\Lambda=\\begin{bmatrix}3.56155281 & 0\\\\0 & -0.56155281\\end{bmatrix}$$\n",
    "\n",
    "$$Q^{-1}=\\begin{bmatrix}0.89720673 & 0.50382896\\\\-0.27816009 & 0.99068183\\end{bmatrix}$$\n",
    "\n",
    "验证\n",
    "\n",
    "${A = Q \\lambda Q^{-1}}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True,  True])"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v = np.array([1.,3.])\n",
    "np.around(A@v) == np.around(Q@L@Qinv@v)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "- 下面可视化变换过程\n",
    "\n",
    "|${Q}$|${\\Lambda}$|${Q^{-1}}$|\n",
    "|-|-|-|\n",
    "|${{\\color{orange}橙} \\to {\\color{red}红}}$|${{\\color{red}红} \\to {\\color{magenta}紫}}$|${{\\color{magenta}紫} \\to {\\color{blue}蓝}}$|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2,) (2,) (2, 2)\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "t1 = np.linalg.inv(Q)@v\n",
    "print(v.shape, t1.shape, L.shape)\n",
    "t2 = L@t1\n",
    "t3 = Q@t2\n",
    "\n",
    "vecs = np.array([v, t1, t2, t3])\n",
    "origin = [0], [0]\n",
    "plt.axis('equal')\n",
    "plt.grid()\n",
    "plt.ticklabel_format(style='sci', axis='both', scilimits=(0,0))\n",
    "plt.quiver(*origin, vecs[:,0], vecs[:,1], color=['orange', 'red', 'magenta', 'blue'], scale=20)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## 矩阵的秩\n",
    "\n",
    "对于一个方形矩阵，不为0的特征值的个数。\n",
    "\n",
    "比如\n",
    "${A=\\begin{bmatrix}1 & 2\\\\4 & 3\\end{bmatrix}}$ 其特征值对角阵是 ${\\Lambda=\\begin{bmatrix}-1 & 0\\\\0 & 5\\end{bmatrix}}$\n",
    "\n",
    "所以${A}$的秩是2，和矩阵的维度一样，称为满秩矩阵。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.,  0.],\n",
       "       [ 0.,  5.]])"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = np.matrix([[1,2],\n",
    "              [4,3]])\n",
    "l, Q = np.linalg.eig(A)\n",
    "L = np.diag(l)\n",
    "L"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "又例如${B=\\begin{bmatrix}3 & -3 & 6\\\\2 & -2 & 4\\\\1 & -1 & 2\\end{bmatrix}}$ 的特征值对角阵是 ${\\Lambda=\\begin{bmatrix}3 & 0& 0\\\\0 & -6\\times10^{-17} & 0\\\\0 & 0 & 3.6\\times10^{-16}\\end{bmatrix} \\approx \\begin{bmatrix}3 & 0& 0\\\\0 & 0 & 0\\\\0 & 0 & 0\\end{bmatrix}}$\n",
    "\n",
    "所以${B}$的秩是1，比矩阵的维度3小，称为欠定矩阵。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[3.00000000e+00, 0.00000000e+00, 0.00000000e+00],\n",
       "       [0.00000000e+00, 5.23364153e-16, 0.00000000e+00],\n",
       "       [0.00000000e+00, 0.00000000e+00, 0.00000000e+00]])"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "B = np.array([[3,-3,6],\n",
    "              [2,-2,4],\n",
    "              [1,-1,2]])\n",
    "lb, Qb = np.linalg.eig(B)\n",
    "Lb = np.diag(lb)\n",
    "Lb"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## 满秩方阵的可逆性\n",
    "\n",
    "证明：${A^{-1} = Q \\Lambda^{-1} Q^{-1}}$\n",
    "\n",
    "$$ I = A^{-1}A $$\n",
    "因为：${A=Q \\Lambda Q^{-1}}$\n",
    "$$ I = A^{-1}Q \\Lambda Q^{-1} $$\n",
    "两边同时乘：${Q\\Lambda^{-1}Q^{-1}}$\n",
    "$$ IQ\\Lambda^{-1}Q^{-1} = A^{-1}Q \\Lambda Q^{-1}Q\\Lambda^{-1}Q^{-1}$$\n",
    "两边同时消去单位阵\n",
    "$$ Q\\Lambda^{-1}Q^{-1} = A^{-1} $$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "- 对角阵求逆只要把对角元素求倒数即可（矩阵除法→算术除法）\n",
    "- 0没有倒数（满秩要求）\n",
    "- 对于满秩方阵的求逆\n",
    "  - 特征值和特征向量\n",
    "  - 算术除\n",
    "  - 矩阵乘"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "练习:\n",
    "\n",
    "验证 ${A = \\begin{bmatrix}1 & 2\\\\3 & 4\\end{bmatrix} \\Rightarrow A^{-1}=\\begin{bmatrix}-0.6 & 0.4\\\\0.8 & -0.2\\end{bmatrix}}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ True,  True],\n",
       "       [ True,  True]])"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = np.matrix([[1,2],\n",
    "              [4,3]])\n",
    "l, Q = np.linalg.eig(A)\n",
    "L = np.matrix(np.diag(l))\n",
    "np.around(Q@L.I@Q.I,1) == np.around(A.I,1)"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
